package n5_测试_卖票_和_转账;


import lombok.extern.slf4j.Slf4j;

import java.util.Random;

/**
 * 转账问题
 */
@Slf4j(topic = "c.T2")
public class T2_转账 {

    public static void main(String[] args) throws InterruptedException {
        Account a = new Account(1000);
        Account b = new Account(1000);

        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                a.transfer(b, randomAmount());
            }
        }, "t1");
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                b.transfer(a, randomAmount());
            }
        }, "t2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
// 查看转账2000次后的总金额
        log.debug("total:{}",(a.getMoney() + b.getMoney()));
    }



    // Random 为线程安全
    static Random random = new Random();
    // 随机 1~100
    public static int randomAmount() {
        return random.nextInt(100) +1;
    }

}


// 账号
class  Account {
    private int money;
    // 1. 初始化金额
    public Account(int money) {
        this.money = money;
    }
    // 2. 获取余额
    public int getMoney() {
        return money;
    }
    // 3. 获取余额
    public void setMoney(int money) {
        this.money = money;
    }
    // 4. 给 目标账户转账 【 存在 两个 共享变量，都需要保护】
    /**------------------------------------------------------------------
    |                                                                   /
    | 方案一： 锁住同一个类 就可以锁住多个要保护的变量                         /
    |      <b>弊端：</b>：  这样同一时间只能两个账户相互转账，其他账户将不能转  /
    |                                                                   /
    |===================================================================*/
    public void transfer(Account target, int amount) {

        synchronized (Account.class) {
//        synchronized (this) {
            if (this.money > amount) {
                this.setMoney(this.getMoney() - amount);
                target.setMoney(target.getMoney() + amount);
            }
        }
    }
}
